package cz.semjobKB.conllx.api.impl;

import cz.semjobKB.conllx.api.ETextPart;
import cz.semjobKB.conllx.api.ISentence;
import cz.semjobKB.conllx.api.ITextPart;
import cz.semjobKB.conllx.api.IWord;

import java.util.ArrayList;
import java.util.List;

/**
 * Methods to operate with the document tree on a sentence level
 */
public class Sentence implements ISentence {

	/**
	 * Serialization
	 */
	private static final long serialVersionUID = -6232642031703828472L;

	/** The words. */
	private final List<IWord> words;

	/** The root. */
	protected Document root = null;

	/** The next sentence. */
	private Sentence nextSentence = null;

	/** The previous sentence. */
	private Sentence previousSentence = null;

	/** The parent paragraph. */
	private final Paragraph parent;

	/** The current word index. */
	private int currentWordIndex = 0;

	/** The text. */
	String text = null;

	/**
	 * Instantiates a new sentence class.
	 * 
	 * @param treeRoot
	 *            the document tree root
	 * @param parentParagraph
	 *            the parent paragraph
	 */
	public Sentence(final Document treeRoot, final Paragraph parentParagraph) {
		this.words = new ArrayList<IWord>();
		this.root = treeRoot;
		this.parent = parentParagraph;
	}

	
	public void setNextSentence(final ISentence next) {
		nextSentence = (Sentence) next;
	}

	
	public Sentence getNextSentence() {
		return nextSentence;
	}

	/**
	 * Gets the previous sentence.
	 * 
	 * @return the previous sentence
	 */
	public Sentence getPreviousSentence() {
		return previousSentence;
	}

	/**
	 * Sets the previous sentence.
	 * 
	 * @param previousSentence
	 *            the new previous sentence
	 */
	public void setPreviousSentence(final Sentence previousSentence) {
		this.previousSentence = previousSentence;
	}

	public String getText() {
		if (text == null) {
			text = "";
			for (IWord word : words) {
				text += word.getText() + " ";
			}
		}
		return text;
	}
	
	public boolean hasNext(final ETextPart part) {
		if (part == ETextPart.WORD) {
			if (root.selectedWord < words.size()) {
				return true;
			} else {
				root.selectedWord = 0;
				return false;
			}
		}
		if (part == ETextPart.SENTENCE) {
			if (root.selectedSentence < parent.getSentences().size()) {
				return true;
			} else {
				root.selectedSentence = 0;
				root.selectedWord = 0;
				return false;
			}
		}
		return false;
	}
	
	public ITextPart getNext(final ETextPart part) {
		if (part == ETextPart.WORD) {
			if (hasNext(part)) {
				IWord word = words.get(root.selectedWord);
				root.selectedWord++;
				return word;
			} else {
				root.selectedWord = 0;
				return null;
			}
		}
		if (part == ETextPart.SENTENCE) {
			if (hasNext(part)) {
				root.selectedSentence++;
				root.selectedWord = 0;
				return this;
			} else {
				root.selectedSentence = 0;
				root.selectedWord = 0;
				return null;
			}
		}
		return null;
	}
	
	public int getWordCount() {
		return this.words.size();
	}

    public void setText(final String text) {
	    this.text = text;
	}

	public void addAllWords(final List<Word> words) {
		this.words.addAll(words);
	}

	public String toString() {
		return "Sentence [words=" + words + ", currentWordIndex=" + currentWordIndex + "]";
	}

	@SuppressWarnings("unchecked")
	public <W extends IWord> List<W> getWords() {
		return (List<W>) words;
	}

	public Word getWord(int k) {		
		return (Word) words.get(k);
	}
}
